//
// Created by Crestimes on 24-6-2.
//
#include <filesystem>
#include <iostream>
#include "LRMap.h"
#include "Parser.h"
#include "ProductionManager.h"
#include "TokenManager.h"
using namespace std;

/**
 * 从文件路径或者文件内容中获取到数据
 * @param pathOrContent 文件路径或者文件内容
 */
vector<string> initBuffs(const string& pathOrContent);

/**
 * 测试入口函数
 * @param name 代码名称
 */
void test(const string& name);

/**
 * 主程序入口
 */
int main(int argc, char* argv[]) {
    test("tiny");
    test("mini_c");
    return 0;
}

void test(const string& name) {
    cout << "Testing " << name << endl;

    // 初始化分词结果数据
    auto buffs = initBuffs("Path:/to/your/" + name + "-token-test.txt");
    const auto tokenManager = TokenManager(buffs);

    // 初始化文法语句
    auto productionBuffs = initBuffs("Path:/to/your/" + name + "-prod.txt");
    auto prodBuildTypeBuffs = initBuffs("Path:/to/your/" + name + "-prod-build-type.txt");
    const auto productionManager = ProductionManager(productionBuffs, prodBuildTypeBuffs);

    // 建立LR(1)/LALR(1)分析表
    const auto lrMap = LRMap(productionManager.productions, productionManager.nameToCharacter,
                             productionManager.nameToProductions, true);
    lrMap.showMap();
    lrMap.showTable();

    // 对分词结果进行语法分析
    auto parser = Parser(lrMap.productions, lrMap.tableMap, lrMap.allEndCharNames, tokenManager.tokens);
    parser.parse();
    cout << endl;
}

vector<string> initBuffs(const string& pathOrContent) {
    // 清空buffs内容
    vector<string> buffs;
    string line;
    if (filesystem::exists(pathOrContent)) {
        // 读取文件内容，存入buffs列表
        if (ifstream f(pathOrContent); f.is_open()) {
            while (getline(f, line)) {
                buffs.emplace_back(line);
            }
            f.close();
        }
        else {
            throw runtime_error("Unable to open file: " + pathOrContent);
        }
    }
    else {
        // 直接是文件内容
        stringstream ss(pathOrContent);
        while (getline(ss, line)) {
            buffs.emplace_back(line);
        }
    }
    return buffs;
}
